<?php

use \GatewayWorker\Lib\Gateway;  

require_once dirname(__DIR__) . '/public.class.model.php';
class Room_Model extends Public_Model
{
	
	/***************************
			common function	
	***************************/
	
	
	/*
		断线
	*/
	public function userDisconnected($arrData)
	{
		if(!isset($arrData['gaming_roomid']) || trim($arrData['gaming_roomid']) == G_CONST::EMPTY_STRING)
		{
			return false;
		}
		if(!isset($arrData['account_id']) || trim($arrData['account_id']) == G_CONST::EMPTY_STRING)
		{
			return false;
		}
		
		$room_id 		= $arrData['gaming_roomid'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		if($this->queryOnlineStatus($room_id, $account_id)){
			$this->writeLog("[$room_id] ($account_id)  is still in room");
			return true;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		//没开局玩过的用户离线，自动从房间中退出
		if($this->queryTicketChecked($room_id, $account_id) == 0) {
			$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
			$zrem_result = $Redis_Model->zremSet($RoomSequence_Key,array($account_id));

			$account_status = Game::AccountStatus_Initial;
		} else {
			$account_status = $this->queryAccountStatus($room_id, $account_id);

			if($account_status == Game::AccountStatus_Ready){	//准备状态下断线， 变为未准备

				$account_status = Game::AccountStatus_Notready;
			}
		}

		$this->updateAccountStatus($room_id, $account_id, $account_status );
		$this->writeLog("[$room_id] ($account_id) 离线");

		//获取房间状态
		$room_status = $this->queryRoomStatus($room_id);
		if($room_status === Redis_CONST::DATA_NONEXISTENT || $room_status == Game::RoomStatus_Closed ){	//房间已经废弃或未激活
			return true;
		}

		//判断是否全部人离线
		$clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
		if(count($clients_of_groupid) == 0)
		{
			$this->deleteRoomTimer($room_id);
			$this->setupClearRoomPassiveTimer($room_id);
		}
		
		return true; 
	}
	
	
	
	/***************************
			logic function	
	***************************/
	
	/*
		创建房间
	*/
	public function createRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['data_key']) || trim($data['data_key']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(createRoom):lack of data_key"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"data_key");
		}
		if(!isset($data['joker']) || !in_array($data['joker'], [0,1,2,3]) )
		{
			$this->logMessage('error', "function(createRoom):lack of joker"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"joker");
		}
		if(!isset($data['horse_count']) || $data['horse_count']<0||$data['horse_count']>8 )
		{
			$this->logMessage('error', "function(createRoom):lack of horse_count"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"horse_count");
		}
		if(!isset($data['qianggang']))
		{
			$this->logMessage('error', "function(createRoom):lack of qianggang"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"qianggang");
		}
		if(!isset($data['ticket_count']) || !in_array($data['ticket_count'], [1,2]))
		{
			$this->logMessage('error', "function(createRoom):lack of ticket_count"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"ticket_count");
		}
        if(!isset($data['client_name'])){
            $data['client_name'] = "wechat";
        }
        if(!isset($data['client_type'])){
            $data['client_type'] = "wechat";
        }
        if(!isset($data['daikai_id'])){
            $data['daikai_id'] = 0;
        }
        //获取随机房间号
        $newRoomNumber = $this->getNewRoomNumber();
		$data_key = $data['data_key'];

		$joker =  $data['joker'] ;
		$horse_count = $data['horse_count'] ;
		$qianggang = $data['qianggang'] ;
		$chengbao = isset($data['chengbao']) ? $data['chengbao'] : 1;
		$spend_ticket_count = $data['ticket_count'] ;
		$total_num = Config::GameNum_EachRound * $spend_ticket_count;

		//获取维护公告
		$alert_type = -1;
		$announcement_result = $this->getGameAnnouncement($account_id);
		if(is_array($announcement_result))
		{
			$alert_type = $announcement_result['alert_type'];
			$alert_text = $announcement_result['alert_text'];
		}
		if($alert_type == 4)
		{
			$room_array['alert_type'] = $alert_type;
			return array("result"=>"-1","operation"=>$operation,"data"=>$room_array,"result_message"=>$alert_text); 
		}
		
		$MMYSQL = $this->initMysql();

		//判断房卡余额
		$my_ticket_count = $MMYSQL->select("ticket_count")->from("room_ticket")->where("account_id=".$account_id)->single();
		$this->writeLog("($account_id) 牌券:" . $my_ticket_count);
		if($my_ticket_count >= $spend_ticket_count){

		} else {
			$this->writeLog("($account_id) 牌券不足");
			$result['alert_type'] = 1;	//1房卡不足
			return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房卡不足"); 
		}

		//判断房间申请记录是否存在
		$room_where = 'data_key="'.$data_key.'"';
		$room_sql = 'select room_id,room_number,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$room_aid = $account_id;
			$is_close = G_CONST::IS_FALSE;
			
			$r_array['create_time'] = $timestamp;
			$r_array['create_appid'] = "aid_".$account_id;
			$r_array['update_time'] = $timestamp;
			$r_array['update_appid'] = "aid_".$account_id;
			$r_array['is_delete'] = G_CONST::IS_FALSE;
			$r_array['data_key'] = $data_key;
			$r_array['account_id'] = $room_aid;
			$r_array['is_close'] = G_CONST::IS_FALSE;
            $r_array['new_room_number'] = $newRoomNumber;
            $r_array['client_name'] = $data['client_name'];
            $r_array['client_type'] = $data['client_type'];
			$r_array['daikai_id'] = $data['daikai_id'];
			$room_id = $MMYSQL->insertReturnID(Room,$r_array);
			if($room_id > 0)
			{
                $room_number = 100000 + $room_id * 10 + mt_rand(1,9);
			}
			else
			{
				$this->logMessage('error', "function(createRoom):用户".$account_id." 创建房间失败："." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>"创建房间失败"); 
			}
			
			$num_updateSql = 'update '.Room.' set room_number="'.$room_number.'" where room_id='.$room_id;
			$num_updateQuery = $MMYSQL->query($num_updateSql);
		}
		else
		{
			$room_id = $room_query[0]['room_id'];
			$room_number = $room_query[0]['room_number'];
			$room_aid = $room_query[0]['account_id'];
			$is_close = $room_query[0]['is_close'];
		}
		
		//添加房间信息到redis
		$Redis_Model = Redis_Model::getModelObject();
		
		$replyArr = array("[roomid]"=>$room_id);
		$Room_Key = strtr(Redis_Const::Room_Key, $replyArr);
		
		$r_mkv[Redis_Const::Room_Field_Number] = $room_number;	//房间号
		$r_mkv[Redis_Const::Room_Field_GameRound] = 1;			//游戏轮数
		$r_mkv[Redis_Const::Room_Field_GameNum] = 0;			//游戏局数
		$r_mkv[Redis_Const::Room_Field_Status] = 1;				//房间状态，1等待、2进行中、3关闭
		$r_mkv[Redis_CONST::Room_Field_Banker] = -1;	//庄家

		$r_mkv[Redis_Const::Room_Field_Joker] = $joker;
		$r_mkv[Redis_Const::Room_Field_Horse] = $horse_count;
		$r_mkv[Redis_Const::Room_Field_QiangGang] = $qianggang;
		$r_mkv[Redis_Const::Room_Field_ChengBao] = $chengbao;
		$r_mkv[Redis_Const::Room_Field_TicketCount] = $spend_ticket_count;
		$r_mkv[Redis_Const::Room_Field_TotalNum] = $total_num;
		$r_mkv[Redis_Const::Room_Field_Creator] = $account_id;  //房间创建者

		$r_mkv[Redis_Const::Room_Field_StartTime] = -1;		//开局时间

		$r_mkv[Redis_Const::Room_Field_BaseScore] = Game::Default_Score; //基本分
        $r_mkv[Redis_CONST::Room_Field_NewNumber] = $newRoomNumber;
		$mset_result = $Redis_Model->hmsetField($Room_Key,$r_mkv);
        $RedisLog_Model = Redis_Model::getModelObjectLogs();
        $RedisLog_Model->hmsetField(Redis_CONST::Room_New_Key,[$newRoomNumber=>json_encode(["room_number"=>$room_number,"game_type"=>Game::Game_Type, "create_time"=>date('Y-m-d H:i:s',$timestamp),"client_name"=>$data['client_name']])]);

        $result['room_id'] = $room_id;
		$result['room_number'] = $room_number;
		$result['is_close'] = $is_close;

		//扣除房卡  房主扣卡模式
		if(Config::Ticket_Mode == 2){  
			$this->balanceTicket($room_id, $account_id, $spend_ticket_count);
		}
		
		$this->writeLog("[$room_id] ($account_id) 创建房间");
		return array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$result,"result_message"=>"创建房间");  
	}


	/*
		用房卡激活房间
	*/
	public function activateRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(PrepareJoinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}


		if(!isset($data['joker']) || !in_array($data['joker'], [0,1,2]) )
		{
			$this->logMessage('error', "function(createRoom):lack of joker"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"joker");
		}
		if(!isset($data['qianggang']))
		{
			$this->logMessage('error', "function(createRoom):lack of qianggang"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"qianggang");
		}

		if(!isset($data['horse_count']) || $data['horse_count']<0||$data['horse_count']>8 )
		{
			$this->logMessage('error', "function(createRoom):lack of horse_count"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"horse_count");
		}
		
		if(!isset($data['ticket_count']) || !in_array($data['ticket_count'], [1,2]))
		{
			$this->logMessage('error', "function(createRoom):lack of ticket_count"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"ticket_count");
		}
		
		$room_number = $data['room_number'];
		
		$MMYSQL = $this->initMysql();
		//判断房间申请记录是否存在
		$room_where = 'room_number='.$room_number;
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$this->writeLog("function(PrepareJoinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		}else{
			$room_id = $room_query[0]['room_id'];
		}

		$horse_count = $data['horse_count'] ;
		$spend_ticket_count = $data['ticket_count'] ;
		$total_num = Config::GameNum_EachRound * $spend_ticket_count;

		$joker =  $data['joker'] ;
		$qianggang = $data['qianggang'] ;
		$chengbao = isset($data['chengbao']) ? $data['chengbao'] : 1;

		$room_status = $this->queryRoomStatus($room_id);
		if($room_status != Game::RoomStatus_Closed){
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间已经被激活"); 
		}

		$MMYSQL = $this->initMysql();

		$my_ticket_count = $MMYSQL->select("ticket_count")->from("room_ticket")->where("account_id=".$account_id)->single();
		$this->writeLog("[$room_id] ($account_id) 牌券:" . $my_ticket_count);
		if($my_ticket_count >= $spend_ticket_count){

		} else {
			$this->writeLog("[$room_id] ($account_id) 牌券不足");
			$result['alert_type'] = 1;	//1房卡不足
			return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房卡不足"); 
		}
		
		//添加房间信息到redis
		$Redis_Model = Redis_Model::getModelObject();
		
		$replyArr = array("[roomid]"=>$room_id);
		$Room_Key = strtr(Redis_Const::Room_Key, $replyArr);
		$r_mkv[Redis_Const::Room_Field_Creator] = $account_id;
		$r_mkv[Redis_Const::Room_Field_Status] = 1;				//房间状态，1等待、2进行中、3关闭

		$r_mkv[Redis_Const::Room_Field_Horse] = $horse_count;
		$r_mkv[Redis_Const::Room_Field_TicketCount] = $spend_ticket_count;
		$r_mkv[Redis_Const::Room_Field_TotalNum] = $total_num;
		$r_mkv[Redis_Const::Room_Field_GameNum] = 0;			//游戏局数

		$r_mkv[Redis_Const::Room_Field_Joker] = $joker;
		$r_mkv[Redis_Const::Room_Field_QiangGang] = $qianggang;
		$r_mkv[Redis_Const::Room_Field_ChengBao] = $chengbao;

		$mset_result = $Redis_Model->hmsetField($Room_Key,$r_mkv);

		 //扣除房卡  房主扣卡模式
		if(Config::Ticket_Mode == 2){ 
			$this->balanceTicket($room_id, $account_id, $spend_ticket_count);
		}
		
		$this->writeLog("[$room_id] ($account_id) 激活了房间");
		$result['room_id'] = $room_id;
		return array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$result,"result_message"=>"创建房间");  
	}

    public function getNewRoomNumber(){
        $ti = microtime();
        list($s,$m) = explode(" ", $ti);
        $newRoomNumber = substr($m + substr($s,2), 4);
        if ($newRoomNumber <= 100000) $newRoomNumber += 100000;
        $RedisLog_Model = Redis_Model::getModelObjectLogs();
        if ($RedisLog_Model->hexistsField('RoomNumber',$newRoomNumber) == Redis_CONST::Key_Nonexistent){
            return $newRoomNumber;
        }else{
            return $this->getNewRoomNumber();
        }
    }
	
	/*
		进入房间
	*/
	public function joinRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(joinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		//判断房间是否存在
		$MMYSQL = $this->initMysql();
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where room_number='.$room_number;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row){
			$this->logMessage('error', "function(joinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		} else {
			$room_id = $room_row['room_id'];
			if($room_row['is_close']){
				$result = array('room_status'=>4);
				return array("result"=>0,"operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
		
		//总分数
		$RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
		$RoomScore_Field_User = strtr(Redis_Const::RoomScore_Field_User, $replyArr);
			
		$rsSeq_score = $Redis_Model->getZscore($RoomSequence_Key,$account_id);
		//判断用户是否已加入房间
		if(Redis_CONST::DATA_NONEXISTENT !== $rsSeq_score)		//已加入
		{
			//获取分数
			$rScore_score = $Redis_Model->hgetField($RoomScore_Key,$RoomScore_Field_User);
			//获取用户所在位置
			$serial_num = $rsSeq_score;

			$account_status = $this->queryAccountStatus($room_id, $account_id);
		}
		else	//未加入
		{
			//判断游戏人数
			$user_count = 0;
			//获取房间所有用户
			$sset_array['key'] = $RoomSequence_Key;
			$sset_array['WITHSCORES'] = "WITHSCORES";
			$gamer_query = $Redis_Model->getSortedSetLimitByAry($sset_array);
			if(Redis_CONST::DATA_NONEXISTENT !== $gamer_query)
			{
				$user_count = count($gamer_query);
			}
			if($user_count >= Game::GameUser_MaxCount)
			{
				$this->writeLog("function(joinRoom):room($room_number) 人数已满"." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房间人数已满");  
			}
			
			$serial_num = -1;
			for($i=1;$i<=Game::GameUser_MaxCount;$i++)
			{
				if(array_search($i,$gamer_query) === false)
				{
					$serial_num = $i;
					break;
				}
			}
			
			if($serial_num == -1)
			{
				$this->logMessage('error', "function(joinRoom):serial_num($serial_num) 无法找到空桌位"." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"数据错误");  
			}
			
			$rSeq_mkv[$serial_num] = $account_id;
			$zadd_result = $Redis_Model->zaddSet($RoomSequence_Key,$rSeq_mkv);
			
			//添加默认分数
			$rScore_score = 0;
			$rScore_mkv[$RoomScore_Field_User] = $rScore_score;
			$hmset_result = $Redis_Model->hmsetField($RoomScore_Key,$rScore_mkv);

			//首次进房初始状态
			$account_status =  Game::AccountStatus_Initial;
			$AccountStatus_Key = strtr(Redis_Const::AccountStatus_Key, $replyArr);
			$mkv[$account_id] = $account_status;
			$mset_result = $Redis_Model->hmsetField($AccountStatus_Key,$mkv);

		}
		
		//绑定用户UID
		$RoomUser_UID = strtr(Game::RoomUser_UID, $replyArr);

		//解绑当前客户端
		/*
		$client_array = Gateway::getClientIdByUid($RoomUser_UID);
		if(is_array($client_array) && count($client_array) > 0)
		{
			foreach($client_array as $bind_client)
			{
				$this->logMessage('error', "function(joinRoom):RoomUser_UID($RoomUser_UID) 多客户的登陆"." in file".__FILE__." on Line ".__LINE__);
				//推送强制下线
				$forceLogout_message = $this->_JSON(array("result"=>"-202","result_message"=>"您的账号在另一地点登陆，您被迫下线。")); 
				Gateway::sendToClient($bind_client, $forceLogout_message);
				//解绑连接
				//Gateway::closeClient($bind_client);
				Gateway::unbindUid($bind_client, $RoomUser_UID);
				Gateway::leaveGroup($bind_client, $room_id);
			}
		}
		*/

		Gateway::bindUid($client_id, $RoomUser_UID);
		Gateway::joinGroup($client_id, $room_id);
		
		//获取房间当前局数
		$game_num = $this->queryGameNumber($room_id);
		$room_status = $this->queryRoomStatus($room_id);
		$room_ary['room_id'] = $room_id;
		$room_ary['room_number'] = $room_number;
		$room_ary['room_status'] = $room_status;
		$room_ary['account_score'] = $rScore_score;
		$room_ary['account_status'] = $account_status;
		$room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);

		$room_ary['serial_num'] = $serial_num;
		$room_ary['game_num'] = $game_num;
		$room_ary['total_num'] = $this->queryTotalNum($room_id);

		$room_ary['scoreboard'] = $this->queryScoreboard($room_id);
		$room_ary['score_summary'] = $this->queryScoreSummary($room_id);	//每局输赢

		$room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);

		$banker_id = $this->queryBanker($room_id);
		if($banker_id <= 0){
			$banker_id = -1;
		}
		$room_ary['banker_id'] = $banker_id;

		$room_ary['my_card'] = $this->queryPlayerCard($room_id, $account_id);
		$room_ary['remain_count'] = $this->queryRemainCardCount($room_id);
		
		//上一个打牌
		$last_user_discard = $this->queryLastUserDiscard($room_id);
		$room_ary['last_user'] = $last_user_discard['last_user'];
		$room_ary['last_discard'] = $last_user_discard['last_discard'];

		$room_ary['joker_card'] = $this->queryJokerCard($room_id);

		//$room_ary['base_score'] = $this->queryBaseScore($room_id);
		$setting = $this->queryRoomSetting($room_id);

		$room_ary['joker'] = isset($setting[Redis_Const::Room_Field_Joker])?$setting[Redis_Const::Room_Field_Joker]:0;
		$room_ary['horse_count'] =isset($setting[Redis_Const::Room_Field_Horse]) ?$setting[Redis_Const::Room_Field_Horse]:0;

		$room_ary['qianggang'] =isset($setting[Redis_Const::Room_Field_QiangGang]) ?$setting[Redis_Const::Room_Field_QiangGang]:0;
		$room_ary['chengbao'] =isset($setting[Redis_Const::Room_Field_ChengBao]) ?$setting[Redis_Const::Room_Field_ChengBao]:1;
		$room_ary['ticket_count'] =isset($setting[Redis_Const::Room_Field_TicketCount]) ?$setting[Redis_Const::Room_Field_TicketCount]:1;

		$room_ary['base_score'] =isset($setting[Redis_Const::Room_Field_BaseScore]) ?$setting[Redis_Const::Room_Field_BaseScore]: Game::Default_Score;

		$room_ary['countdown'] =  $this->queryCountdown($room_id, Game::LimitTime_BreakRoom);
        $room_ary['creator_id'] = $setting[Redis_CONST::Room_Field_Creator];
		//推送房间信息
		$room_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
		$this->pushMessageToCurrentClient($room_return);
		
		//返回所有玩家状态给进房玩家
		$allGamer = $this->getGamerInfo($room_id);
		if(is_array($allGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
			$this->pushMessageToCurrentClient($currentGamer_return);
		}

		$this->notyfyPlayingStatus($room_id, $account_id);
		
		//推送当前玩家状态给其他玩家
		$currentGamer = $this->getGamerInfo($room_id,$account_id);
		if(is_array($currentGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer,"result_message"=>"某玩家状态");
			$this->pushMessageToGroup($room_id, $currentGamer_return, $client_id);
		}

		//保存用户当前房间,用户ID
		$_SESSION['gaming_roomid'] = $room_id;
		$_SESSION['account_id'] = $account_id;
		
		$this->writeLog("[$room_id] ($account_id) 进入房间");
		return OPT_CONST::NO_RETURN;
	}

	protected function notyfyPlayingStatus($room_id, $account_id)
	{
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$active_user =  $this->queryActiveUser($room_id);
		if($active_user > 0){

			$DaiQiangGang_Key = strtr(Redis_Const::DaiQiangGang_Key, $replyArr);
			if($Redis_Model->scard($DaiQiangGang_Key) == 0){ //寻常打牌过程

				$playing_status = $this->queryActiveType($room_id);
				if($playing_status == Game::PlayingStatus_Choosing ){

					$hu_flag = 0;
					$gang_flag = 0;
					$new_card = $this->queryNewCard($room_id);
					//通知:哪位出牌
					if($active_user == $account_id){	//自己
						
						if($new_card){
							$hu_flag = $this->checkHu($room_id, $account_id, $new_card);
							$gang_flag = $this->checkGang($room_id, $account_id, $new_card);
						} else {
							$new_card = "";
						}
					} else {	//其他人
						$new_card = $new_card > 0 ? -1 : ""; //-1表示其他人只看到新牌的背面，空表示没有新牌
					}
					$noty_arr = array(
						'account_id' => $active_user,
						'playing_status' => Game::PlayingStatus_Choosing,
						'limit_time'	 => $this->queryCountdown($room_id, Game::LimitTime_Choosing),
						'remain_count' => $this->queryRemainCardCount($room_id),
						'new_card' => $new_card,
						'hu_flag' => $hu_flag,
						'gang_flag' => $gang_flag,
						);
					$msg_arr = array("result"=>"0","operation"=>"NotyChooseCard","data"=>$noty_arr,"result_message"=>"通知出牌");
					$this->pushMessageToCurrentClient($msg_arr);

				} else if($playing_status == Game::PlayingStatus_Peng || $playing_status == Game::PlayingStatus_Gang){

					if($active_user == $account_id){	//自己
						$noty_arr = array(
							'account_id' => $active_user,
							'playing_status' => $playing_status,
							'limit_time'	 => $this->queryCountdown($room_id, Game::LimitTime_PengGang),
							);
						$msg_arr = array("result"=>"0","operation"=>"NotyPengGang","data"=>$noty_arr,"result_message"=>"通知碰杠");
					} else {	//其他人
						$noty_arr = array(
							'account_id' => "",
							'playing_status' => Game::PlayingStatus_Waiting,
							'limit_time'	 => $this->queryCountdown($room_id, Game::LimitTime_PengGang),
							);
						$msg_arr = array("result"=>"0","operation"=>"NotyPengGang","data"=>$noty_arr,"result_message"=>"通知碰杠");
					}
					$this->pushMessageToCurrentClient($msg_arr);	
				}

			} else {	//有人在抢杠胡

				$can_qiang =  $Redis_Model->sismemberSet($DaiQiangGang_Key, $account_id);
				if($can_qiang){
					$noty_arr = array(
						'account_id' => $account_id,
						'playing_status' => Game::PlayingStatus_QiangGang,
						'limit_time'	 => $this->queryCountdown($room_id, Game::LimitTime_QiangGang),
						'card' => $this->queryNewCard($room_id),
						);
					$msg_arr = array("result"=>"0","operation"=>"NotyQiangGang","data"=>$noty_arr,"result_message"=>"通知抢杠");
					$this->pushMessageToCurrentClient($msg_arr);
				} else {

					$noty_arr = array(
						'account_id' => "",
						'playing_status' => Game::PlayingStatus_Waiting,
						'limit_time'	 => $this->queryCountdown($room_id, Game::LimitTime_QiangGang),
						);
					$msg_arr = array("result"=>"0","operation"=>"NotyQiangGang","data"=>$noty_arr,"result_message"=>"通知抢杠");
					$this->pushMessageToCurrentClient($msg_arr);
				}

			}

		} 
	}


	/*
		上传经纬度信息
	*/
	public function uploadGeo($arrData)
	{
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_id'])&& $data['room_id'] > 0) )
		{
			$this->logMessage('error', "function(uploadGeo):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}

		if(!isset($data['longitude']) || !isset($data['latitude']) )
		{
			$this->logMessage('error', "function(uploadGeo):lack of longitude or latitude"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"longitude/latitude");
		}
		
		$room_id = $data['room_id'];
		$longitude = $data['longitude'];
		$latitude = $data['latitude'];

		$this->updateAccountGeo($room_id, $account_id, $longitude, $latitude);
		
		$msg_arr = array("result"=>0,"operation"=>"AccountGeo","data"=>array(
			'account_id'=>$account_id,
			'longitude'=>$longitude,
			'latitude'=>$latitude,
			),"result_message"=>"地理位置");

		$this->pushMessageToGroup($room_id, $msg_arr);
	}


	/*
		拉取房间信息
	*/
	public function pullRoomInfo($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_id'])&& $data['room_id'] > 0) )
		{
			$this->logMessage('error', "function(pullRoomInfo):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];

		$is_legal = $this->checkRequestClientLegal($client_id,$room_id,$account_id);
		if(!$is_legal)
		{
			$this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
			//推送强制下线
			$illegal_message = $this->_JSON(array("result"=>"-203","result_message"=>"illegal opt")); 
			Gateway::sendToCurrentClient($illegal_message);
			return OPT_CONST::NO_RETURN;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
		
		//总分数
		$RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
		$RoomScore_Field_User = strtr(Redis_Const::RoomScore_Field_User, $replyArr);
			
		$rsSeq_score = $Redis_Model->getZscore($RoomSequence_Key,$account_id);
		//判断用户是否已加入房间
		if(Redis_CONST::DATA_NONEXISTENT !== $rsSeq_score)		//已加入
		{
			//获取分数
			$rScore_score = $Redis_Model->hgetField($RoomScore_Key,$RoomScore_Field_User);
			//获取用户所在位置
			$serial_num = $rsSeq_score;

			$account_status = $this->queryAccountStatus($room_id, $account_id);
		}
		else	//未加入
		{
			$this->logMessage('error', "function(pullRoomInfo):account($account_id) not join room"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"用户未加入房间"); 
		}
		
		$room_ary['account_score'] = $rScore_score;
		$room_ary['account_status'] = $account_status;
		$room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);

		$room_ary['serial_num'] = $serial_num;

		$room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);

		$banker_id = $this->queryBanker($room_id);
		if($banker_id <= 0){
			$banker_id = -1;
		}
		$room_ary['banker_id'] = $banker_id;

		$room_ary['my_card'] = $this->queryPlayerCard($room_id, $account_id);
		$room_ary['remain_count'] = $this->queryRemainCardCount($room_id);
		
		//上一个打牌
		$last_user_discard = $this->queryLastUserDiscard($room_id);
		$room_ary['last_user'] = $last_user_discard['last_user'];
		$room_ary['last_discard'] = $last_user_discard['last_discard'];

		$setting = $this->queryRoomSetting($room_id);

		//返回所有玩家状态给进房玩家
		$allGamer = $this->getGamerInfo($room_id);
		if(!is_array($allGamer))
		{
			$this->logMessage('error', "function(pullRoomInfo):room($room_number) no player"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间没有其他用户");
		}

		$pull_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"拉取房间信息","all_gamer_info"=>$allGamer);

		$this->pushMessageToCurrentClient($pull_return);

		$this->notyfyPlayingStatus($room_id, $account_id);

		$this->logMessage('error', "function(pullRoomInfo):用户$account_id 拉取房间$room_id 信息"." in file".__FILE__." on Line ".__LINE__);
		$this->logMessage('error', "function(pullRoomInfo):pull_return:".json_encode($pull_return). " in file".__FILE__." on Line ".__LINE__);
	
		return OPT_CONST::NO_RETURN;
	}


	//{"operation":"TestDouble","account_id":"2","data":{"room_id":"37","serial_num":"4"}}
	public function testDouble($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(testDouble):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}

		$room_id = $data['room_id'];
		$serial_num = $data['serial_num'];

		$currentGamer_test = $this->getGamerInfo($room_id,$account_id);
		$currentGamer_test['serial_num'] = $serial_num;
		$msg_arr = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer_test,"result_message"=>"某玩家状态");

		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$room_aid = strtr(Game::RoomUser_UID, $replyArr);

		print_r($msg_arr);

		$this->pushMessageToAccount($room_id, $account_id, $msg_arr);
		return OPT_CONST::NO_RETURN;
	}
	
	
	/*
		获取房间所有用户
	*/
	protected function getGamerInfo($room_id,$account_id=-1)
	{
		$result = array();
		
		$Redis_Model = Redis_Model::getModelObject();
		$MMYSQL = $this->initMysql();
		
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		//房间玩家集合
		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);
		
		//获取房间所有用户
		$sset_array['key'] = $RoomSequence_Key;
		$sset_array['WITHSCORES'] = "WITHSCORES";
		$gamer_query = $Redis_Model->getSortedSetLimitByAry($sset_array);
		if(Redis_CONST::DATA_NONEXISTENT !== $gamer_query)
		{
			foreach($gamer_query as $gamer_id=>$serial_num)
			{
				//获取玩家信息
				$account_where = 'account_id="'.$gamer_id.'"';
				$account_sql = 'select nickname,headimgurl from '.WX_Account.' where '.$account_where;
				$account_query = $MMYSQL->query($account_sql);
				if(!is_array($account_query) || count($account_query) == 0 )
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['serial_num'] = $serial_num;
				$info['account_id'] = $gamer_id;
				$info['nickname'] = $account_query[0]['nickname'];
				$info['headimgurl'] = $account_query[0]['headimgurl'];
				
				
				//获取玩家当前积分
				$rScore_score = $this->queryAccountScore($room_id, $gamer_id);
				if(Redis_CONST::DATA_NONEXISTENT === $rScore_score)
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) score not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['account_score'] = $rScore_score;
				
				//获取玩家当前状态
				$rStatus = $this->queryAccountStatus($room_id, $gamer_id);
				if(Redis_CONST::DATA_NONEXISTENT === $rStatus)
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) status not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['account_status'] = $rStatus;
				$info['online_status'] = $this->queryOnlineStatus($room_id, $gamer_id);
				$info['ticket_checked'] = $this->queryTicketChecked($room_id, $gamer_id);

				$geo = $this->queryAccountGeo($room_id, $gamer_id);
				$info['longitude'] = $geo['longitude'];
				$info['latitude']  =  $geo['latitude'];

				$info['card_count'] = $this->queryPlayerCardCount($room_id, $gamer_id);
				$info['discard'] = $this->queryDiscard($room_id, $gamer_id);
				$info['peng_card'] = $this->queryPengCard($room_id, $gamer_id);
				$info['ming_gang'] = $this->queryMingGang($room_id, $gamer_id);
				$info['an_gang'] = $this->queryAnGang($room_id, $gamer_id);
				
				if($account_id == $gamer_id)
				{
					return $info;
				}
				
				$result[] = $info;
				
			}
		}
		
		return $result;
	}


	/*
		进房之前的查询
	*/
	public function prepareJoinRoom($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(PrepareJoinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		//判断房间是否存在
		$MMYSQL = $this->initMysql();
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where room_number='.$room_number;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row){
			$this->logMessage('error', "function(prepareJoinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		} else {
			$room_id = $room_row['room_id'];
			if($room_row['is_close']){
				$result = array('room_status'=>4);
				return array("result"=>0,"operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}

		$user_count = 0;
		$alert_text = "";
		$room_status = $this->queryRoomStatus($room_id);
		$setting = $this->queryRoomSetting($room_id);
		$joker =isset($setting[Redis_Const::Room_Field_Joker]) ?$setting[Redis_Const::Room_Field_Joker]:0;
		$horse_count =isset($setting[Redis_Const::Room_Field_Horse]) ?$setting[Redis_Const::Room_Field_Horse]:0;
		$ticket_count = isset($setting[Redis_Const::Room_Field_TicketCount]) ?$setting[Redis_Const::Room_Field_TicketCount]:1;
		$qianggang =isset($setting[Redis_Const::Room_Field_QiangGang]) ?$setting[Redis_Const::Room_Field_QiangGang]:1;
		$chengbao =isset($setting[Redis_Const::Room_Field_ChengBao]) ?$setting[Redis_Const::Room_Field_ChengBao]:1;
		$room_array = array(
			'user_count'=>$user_count,
			'alert_text' => $alert_text,
			'room_status' => $room_status,
			'joker' => $joker,
			'horse_count' => $horse_count,
			'ticket_count' => $ticket_count,
			'qianggang' => $qianggang,
			'chengbao' => $chengbao,
            'creator_id'     => $setting[Redis_Const::Room_Field_Creator],
			);

		//获取维护公告
		$alert_type = -1;
		$announcement_result = $this->getGameAnnouncement($account_id);
		if(is_array($announcement_result))
		{
			$alert_type = $announcement_result['alert_type'];
			$alert_text = $announcement_result['alert_text'];
		}
		if($alert_type == 4)
		{
			$room_array['alert_type'] = $alert_type;
			return array("result"=>"1","operation"=>$operation,"data"=>$room_array,"result_message"=>$alert_text); 
		}

		//判断房卡余额
		if(Config::Ticket_Mode == 1){
			$spend_ticket_count = $this->queryTicketCount($room_id);
			$my_ticket_count = $MMYSQL->select("ticket_count")->from("room_ticket")->where("account_id=".$account_id)->single();
			$this->writeLog("[$room_id] ($account_id) 牌券:" . $my_ticket_count);
			if($my_ticket_count >= $spend_ticket_count || $this->queryTicketChecked($room_id, $account_id) >= 1){

			} else {
				$this->writeLog("[$room_id] ($account_id) 牌券不足");
				$room_array['alert_type'] = 1;	//1房卡不足
				return array("result"=>"1","operation"=>$operation,"data"=>$room_array,"result_message"=>"房卡不足"); 
			}
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$RoomSequence_Key = strtr(Redis_Const::RoomSequence_Key, $replyArr);

		//房间人
		$room_users = array();
		$is_member = false;
		//获取房间所有用户
		$sset_array['key'] = $RoomSequence_Key;
		$gamer_query = $Redis_Model->getSortedSetLimitByAry($sset_array);
		if(Redis_CONST::DATA_NONEXISTENT !== $gamer_query)
		{
			foreach($gamer_query as $gamer_id)
			{
				//获取玩家信息
				$account_where = 'account_id="'.$gamer_id.'"';
				$account_sql = 'select account_id,nickname from '.WX_Account.' where '.$account_where;
				$row = $MMYSQL->row($account_sql);
				if($row){
					$room_users[] = $row['nickname'];
					$room_array['user_count']++;
					if($row['account_id'] == $account_id){
						$is_member = true;
					}
				} 
			}
		}

		if($room_array['user_count'] == 0 || $is_member){

		} else {
			if($room_array['user_count'] >= Game::GameUser_MaxCount){
				$this->writeLog("[$room_id] ($account_id) PrepareJoinRoom 人数已满");
				$room_array['alert_type'] = 2;	//2人数已满
				return array("result"=>"1","operation"=>$operation,"data"=>$room_array,"result_message"=>"房间人数已满");  
			} 

			$user_str = implode("、", $room_users);
			$room_array['alert_text'] = "房间中有".$user_str."，是否加入？";
		}

		return array("result"=>"0","operation"=>$operation,"data"=>$room_array,"result_message"=>"进房询问");  
	}

	protected function getGameAnnouncement($account_id)
	{
		//var_dump($account_id);

		$timestamp = time();

		$MMYSQL = $this->initMysql();

		$game_type = Game::Game_Type;

		$announcement_where = 'game_type='.$game_type.' and announce_time<='.$timestamp.' and end_time>'.$timestamp.' and is_delete=0';
		$announcement_sql = 'select announce_time,service_time,end_time,announce_text,service_text from '.Game_Announcement.' where '.$announcement_where;
		$announcement_query = $MMYSQL->query($announcement_sql);
		if(is_array($announcement_query) && count($announcement_query) > 0)
		{
			$announce_time = $announcement_query[0]['announce_time'];
			$service_time = $announcement_query[0]['service_time'];
			$end_time = $announcement_query[0]['end_time'];
			$announce_text = $announcement_query[0]['announce_text'];
			$service_text = $announcement_query[0]['service_text'];

			if($timestamp >= $service_time)
			{
				$array['alert_type'] = 4;
				$array['alert_text'] = $service_text;
			}
			else
			{
				$array['alert_type'] = 4;
				$array['alert_text'] = $announce_text;
			}

			//获取白名单用户
			$whilelist_sql = 'select data_id from '.Game_Whilelist.' where account_id='.$account_id.' and is_delete=0';
			$whilelist_query = $MMYSQL->query($whilelist_sql);
			if(is_array($whilelist_query) && count($whilelist_query) > 0)
			{
				$this->logMessage('error', "function(getGameAnnouncement):白名单用户:".$account_id." in file".__FILE__." on Line ".__LINE__);
				return true;
			}
			else
			{
				return $array;
			}
		}

		return true;
	}
	
	
	/*
		准备操作
	*/
	public function readyStart($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(readyStart):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];

		$is_legal = $this->checkRequestClientLegal($client_id,$room_id,$account_id);
		if(!$is_legal)
		{
			$this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
			//推送强制下线
			$illegal_message = $this->_JSON(array("result"=>"-203","result_message"=>"illegal opt")); 
			Gateway::sendToCurrentClient($illegal_message);
			return OPT_CONST::NO_RETURN;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		
		//获取玩家当前状态，是否未准备
		$rStatus = $this->queryAccountStatus($room_id, $account_id);
		if(Redis_CONST::DATA_NONEXISTENT === $rStatus || !in_array($rStatus, [Game::AccountStatus_Initial, Game::AccountStatus_Notready])  )
		{
			$this->writeLog("function(readyStart):account($account_id) status($rStatus) invalid"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"状态异常"); 
		}
		
		//更新用户状态
		$rStatus = Game::AccountStatus_Ready;
		$this->updateAccountStatus($room_id, $account_id, $rStatus);

		$this->startGame($room_id);
		
		return OPT_CONST::NO_RETURN;
	}
	
	/*
		取消准备操作
	*/
	public function readyCancel($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(readyCancel):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		
		//设置当前状态，已准备
		//更新用户状态
		$rStatus = Game::AccountStatus_Notready;
		$this->updateAccountStatus($room_id, $account_id, $rStatus);

		$ready_count = $this->queryReadyCount($room_id);
		return OPT_CONST::NO_RETURN;
	}
	
	/*
		历史积分榜
	*/
	public function historyScoreboard($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		$MMYSQL = $this->initMysql();
		if(isset($data['room_number']) && $data['room_number'] > 0 )
		{
			$room_number = $data['room_number'];
			//判断房间申请记录是否存在
			$room_where = 'room_number='.$room_number;
			$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
			$room_query = $MMYSQL->query($room_sql);
			if(!is_array($room_query) || count($room_query) == 0 )
			{
				$this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
			}else{
				$room_id = $room_query[0]['room_id'];
			}
		} else if(isset($data['room_id'])&& $data['room_id'] > 0) {
			$room_id = $data['room_id'];
		} else {
			$this->logMessage('error', "function(historyScoreboard):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}

		$scoreboards = array();

		$sql = 'select * from room_scoreboard where room_id='.$room_id.' and game_type='.Game::Game_Type.' order by create_time desc limit 10';
		$query = $MMYSQL->query($sql);
		if(!is_array($query) )
		{
			$this->writeLog("function(historyScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__);
			//return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"没积分榜");  
		}else{
			foreach ($query as $row) {

				$name_board = array();
				$scoreboard = json_decode($row['board']);
				$create_time = $row['create_time'];
				
				if($scoreboard){
					foreach ($scoreboard as $account_id => $score) {
						$account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
						$name = $MMYSQL->single($account_sql);
						$name_board[] = array('name'=>$name, 'score'=>$score);
					}
					$scoreboards[] = array('time'=>$create_time, 'scoreboard'=>$name_board);
				}
			}
		}
		return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");  
	}

	/*
		最后一局积分榜
	*/
	public function lastScoreboard($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(lastScoreboard):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		$MMYSQL = $this->initMysql();
		//判断房间申请记录是否存在
		$room_where = 'room_number='.$room_number;
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		}else{
			$room_id = $room_query[0]['room_id'];
		}

		$scoreboards = new stdClass();
		$sql = 'select * from room_scoreboard where room_id='.$room_id.' and game_type='.Game::Game_Type.' order by create_time desc limit 1';
		$query = $MMYSQL->query($sql);
		if(!is_array($query) )
		{
			$this->writeLog("function(lastScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__); 
		}else{
			foreach ($query as $row) {

				$name_board = array();
				$scoreboard = json_decode($row['board']);
				$create_time = $row['create_time'];
				$game_num = $row['game_num'];
				if($game_num <= 0)
				{
					$game_num = Config::GameNum_EachRound;
				}
				
				if($scoreboard){
					foreach ($scoreboard as $account_id => $score) {
						$account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
						$name = $MMYSQL->single($account_sql);
						$name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
					}
					$scoreboards = array('time'=>$create_time, 'scoreboard'=>$name_board,'game_num'=>$game_num);
				}
			}
		}
		
		return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");  
	}

    public function closeRoom($arrData)
    {
        $operation = $arrData['operation'];
        $data = $arrData['data'];
        $account_id = $arrData['account_id'];
        $room_number = $data['room_number'];

//        $timer_id = $data['timer_id'];
//
//        $this->writeLog("[$room_id] 触发三分钟自动解散房间");

//        $current_timer_id = $this->queryTimerId($room_id);
//        if($current_timer_id == $timer_id){
//            $this->updateTimer($room_id, -1);
//        } else {
//            //timer对不上，返回
//            $this->writeLog("function(breakRoomPassive):timer对不上($current_timer_id != $timer_id)"." in file".__FILE__." on Line ".__LINE__);
//            return false;
//        }

//        $clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
//        //判断是否全部人离线
//        if(count($clients_of_groupid) > 0)
//        {
//            $this->writeLog("[$room_id] 房间有人也解散房间");
//
//            $msg_arr = array("result"=>"0","operation"=>"BreakRoom","data"=>array('room_id'=>$room_id),"result_message"=>"解散房间");
//            $this->pushMessageToGroup($room_id, $msg_arr);
//
//        } else {
//
//        }
        $MMYSQL = $this->initMysql();

        $room_where = 'room_number='.$room_number.' and is_close =0';
        $room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
        $room_query = $MMYSQL->query($room_sql);
        if(!is_array($room_query) || count($room_query) == 0 )
        {
            $this->writeLog("function(closeRoomManager):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"房间不存在");
        }else{
            $room_id = $room_query[0]['room_id'];
        }

        if ($room_query[0]['account_id'] != $account_id){
            $this->writeLog("function(closeRoomManager):room($room_number) no auth"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"不是管理员，不能关闭房间");
        }

        $this->writeLog("[$room_id] 触发群主清房间");

        $Redis_Model = Redis_Model::getModelObject();
        $replyArr = array("[roomid]"=>$room_id);
        $RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);

        $game_num = $this->queryGameNumber($room_id);
        $creator = $this->queryCreator($room_id);

        if(Config::Ticket_Mode==2 && $game_num==0 && $creator>0){
            $spend_ticket_count = $this->queryTicketCount($room_id);
            $this->balanceTicket($room_id, $creator, - $spend_ticket_count);
        }

        //保存积分榜
        if($game_num > 0){
            $Room_Key = strtr(Redis_Const::Room_Key, $replyArr);
            $round = $Redis_Model->hincrbyField($Room_Key, Redis_Const::Room_Field_GameRound, 1);
            $this->writeLog("[$room_id] 第".($round-1)."轮 结束!");

            $setting = $this->queryRoomSetting($room_id);
            //$round = $setting['ground'];
            $game_info['room_id'] = $room_id;
            $game_info['game_type'] = Game::Game_Type;
            $game_info['dealer_num'] = Config::Dealer_Num;
            $game_info['round'] = $round-1;

            $scoreboard = array();
            if(isset($setting['scoreboard']) && $setting['scoreboard']){
                $board_json_str = $setting['scoreboard'];
                $scoreboard = json_decode($board_json_str, true); //转为关联数组
            } else {
                $scoreboard = $Redis_Model->hgetallField($RoomScore_Key);

                //保存积分榜
                if(is_array($scoreboard)){
                    $ticket_checked_user = $this->queryTicketCheckedUser($room_id);
                    foreach ($scoreboard as $key => $value) {
                        if(!in_array($key, $ticket_checked_user)){
                            //未扣房卡的用户不显示在积分榜上
                            unset($scoreboard[$key]);
                        }
                    }
                    $board_json_str = json_encode($scoreboard);
                } else {
                    $scoreboard = array();
                    $board_json_str = "";
                }
            }

            $MMYSQL = $this->initMysql();
            $name_board = array();
            foreach ($scoreboard as $account_id => $score) {
                $account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
                $name = $MMYSQL->single($account_sql);
                $name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
            }

            //规则文本
            $rule_text = $this->formatRuleText($room_id);
            $balance_scoreboard = array('time'=>time(), 'scoreboard'=>$name_board,'game_num'=>$game_num);
            $balance_board_json_str = json_encode($balance_scoreboard['scoreboard']);

            $start_time = $this->queryStartTime($room_id);

            $board_array['start_time'] = $start_time;
            $board_array['create_time'] = time();
            $board_array['is_delete'] = G_CONST::IS_FALSE;
            $board_array['game_type'] = Game::Game_Type;  //游戏6 麻将
            $board_array['room_id'] = $room_id;
            $board_array['round'] = $round - 1;
            $board_array['game_num'] = $game_num;
            $board_array['rule_text'] = $rule_text;
            $board_array['board'] = $board_json_str;
            $board_array['balance_board'] = $balance_board_json_str;
            $board_id = $MMYSQL->insertReturnID(Room_Scoreboard,$board_array);

            //保存用户积分
            $game_info['score_board'] = $scoreboard;
            $this->saveAccountGameScore($game_info);
        }
        Gateway::closeCurrentClient();
        $client_list = Gateway::getClientInfoByGroup($room_id);
        foreach ($client_list as $client_id=>$item) {
            Gateway::closeClient($client_id);
        }
        //清理房间
        $this->clearRoom($room_id);

        return true;
    }
}